package org.raymond.iworks.study.basic.designpattern.visitor.singledispatch;

/**
 * @author raymond
 * @version V1.0
 * @Description: TODO
 * 单分派:
 * 即执行哪个对象的方法,根据对象的运行时类型决定;执行对象的哪个方法,根据方法参数的编译时类型决定.
 * 选择哪个对象 运行时决定
 * 选择哪个方法 编译时决定
 * 双分派:
 * 即执行哪个对象的方法,根据对象的运行时类型决定;执行对象的哪个方法,根据方法参数的运行时类型决定.
 * 选择哪个对象 运行时决定
 * 选择哪个方法 运行时决定
 *
 * new对象时,我们new的是Child对象,通过call方法的调用结果可知,最终打印出的是I'm Child.
 * 即App类的call方法中,到底调用Parent的call还是会调用Child的call,由我们创建的对象实例类型决定,是运行时决定的,即所谓多态.
 * 而通过saveName方法的调用结果可知,尽管我们new的是Child对象,结果调用的却是形参类型是Parent的那个重载,
 * 由此可知,这里决定调用那个saveName重载,在编译时就决定了.
 * Java支持单分派,不支持多分派.
 * 也因此得知,Java语言中的函数重载,并不是在运行时,根据传递给函数的参数的实际类型,来决定调用哪个重载函数,
 * 而是在编译时,根据传递给函数的参数的声明类型,来决定调用哪个重载函数.
 * 即Java语言中,多态是动态绑定,函数重载是静态绑定.
 *
 * 静态绑定与动态绑定
 * 重写是动态绑定,重载是静态绑定.
 *
 * jdk17 preview: switch matching, 也许可以解决这个问题
 */
public class App {
    public void call(Parent p){
        p.call();
    }
    public void sayName(Parent p){
        System.out.println("saveName重载,参数类型: Parent");
    }
    public void sayName(Child c){
        System.out.println("saveName重载,参数类型: Child");
    }

    public static void main(String[] args) {
        App app = new App();
        Parent obj = new Child();
        app.call(obj);
        app.sayName(obj);
    }
}
